package org.one.stone.soup.grfxML.plugin.builder;

import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.Hashtable;
import java.util.Vector;

import org.one.stone.soup.grfxML.DataMouse;
import org.one.stone.soup.grfxML.DataNode;
import org.one.stone.soup.grfxML.DataPoint;
import org.one.stone.soup.grfxML.DataPoints;
import org.one.stone.soup.grfxML.DataPolygon;
import org.one.stone.soup.grfxML.DataState;
import org.one.stone.soup.grfxML.GrfxMLEngine;
import org.one.stone.soup.grfxML.plugin.SimplePlugin;
import org.one.stone.soup.grfxML.plugin.grfxMLCaster;
import org.one.stone.soup.mjdb.data.field.DataLinker;
import org.one.stone.soup.mjdb.data.field.Field;
import org.one.stone.soup.mjdb.data.field.LockException;
import org.one.stone.soup.xml.XmlElement;

public class Pen extends SimplePlugin implements MouseMotionListener{

	private static final int ARG_POLY = 0;

	private DataNode node;
	private DataNode backNode;
	private boolean processing = false;
	private boolean listening = false;

	private DataPolygon poly;
	private DataPoints polyPoints;
	private DataMouse mouse;

	private Hashtable penSettings = new Hashtable();
	private Vector setters = new Vector();

	private class PenSetting
	{
		public XmlElement size;
		public XmlElement color;
	}
/**
 * NodeBuilder constructor comment.
 */
public Pen(GrfxMLEngine engine){
	super(engine);

	poly = new DataPolygon();
	polyPoints = poly.getPoints();
}
/**
 * initialize method comment.
 */
public void initialize()
{
	node = parent.getParent();
	mouse = getEngine().getAPI().getMouse();

	backNode = new DataNode(getEngine());
	try{
		backNode.getTranslation().getPosition().setValueX(node.getTranslation().getPositionView().getValueX(),this);
		backNode.getTranslation().getPosition().setValueY(node.getTranslation().getPositionView().getValueY(),this);
		getEngine().getAPI().getBase().getBACKGROUND().getChildren().add(backNode,this);

		getEngine().getAPI().commit();
	}
	catch(LockException e){}

	XmlElement pallet = parent.getPluginXml();
	if(pallet==null)
	{
		return;
	}
	for(int loop=0;loop<pallet.getElementCount();loop++)
	{
		XmlElement xSetting = pallet.getElementByIndex(loop);

		PenSetting setting = new PenSetting();
		setting.size = xSetting.getElementByName("size");
		setting.color = xSetting.getElementByName("color");

		penSettings.put(getPath()+xSetting.getName(),setting);
	}
}
/**
 * process method comment.
 */
public void process()
{
	if(processing==true)
		return;

	if(listening==false)
	{
		getEngine().getController().getComponent().addMouseMotionListener(this);
		listening = true;
	}

	processing = true;

	try{
		if(mouse.getButton1Released().getValue()==true)
		{
			DataPolygon newPoly = (DataPolygon)poly.getClone();
			backNode.getShape().add(newPoly,this);

			getEngine().getAPI().commit();
			getEngine().getAPI().refreshBackground();

			polyPoints = poly.getPoints();
			polyPoints.setEmpty();
		}

		for(int loop=0;loop<setters.size();loop++)
		{
			if( ((DataState)setters.elementAt(loop)).getValue()==true )
			{
				PenSetting newSettings = (PenSetting)penSettings.get(((DataState)setters.elementAt(loop)).getId());

				poly.getColor().copyFromgrfxML( newSettings.color );
				poly.getThickness().copyFromgrfxML( newSettings.size );

				((DataState)setters.elementAt(loop)).setValue(false,this);
				processing = false;
				return;
			}
		}

	}
	catch(Exception e){}

	processing = false;
}
/**
 * register method comment.
 */
public void register(DataLinker store)
{
	poly = grfxMLCaster.cast(poly,getArg(poly,ARG_POLY,store));

	DataState state = new DataState();
	setters = new Vector();
	int arg=1;
	while(true)
	{
		Field field = (Field)getArg(state,arg,store);
		if(field==state)
		{
			break;
		}
		setters.addElement(field);
		arg++;
	}
}
/**
 * replace method comment.
 */
public void replace(Field oldObj, Field newObj)
{
	poly = grfxMLCaster.replace(poly,oldObj,newObj);

	for(int loop=0;loop<setters.size();loop++)
	{
		if(oldObj==setters.elementAt(loop))
		{
			setters.removeElementAt(loop);
			setters.addElement(newObj);
		}
	}
}
/**
 * stop method comment.
 */
public void stop()
{
	try{
		getEngine().getController().getComponent().removeMouseMotionListener(this);
		listening = false;

		DataPolygon newPoly = (DataPolygon)poly.getClone();
		backNode.getShape().add(newPoly,this);

		getEngine().getAPI().commit();
		getEngine().getAPI().refreshBackground();

		polyPoints = poly.getPoints();
		polyPoints.setEmpty();
	}
	catch(Exception e){}
}

	/* (non-Javadoc)
	 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
	 */
	public void mouseDragged(MouseEvent e) {

		if(parent.getRunning().getValue()==false)
		{
			stop();
			return;
		}

		int x=e.getX();
		int y=e.getY();

		x = x-node.getTranslation().getPositionView().getValueX();
		y = y-node.getTranslation().getPositionView().getValueY();

		try{
			polyPoints.add(new DataPoint(x,y),this);
		}
		catch(Exception ex)
		{
		}
	}

	/* (non-Javadoc)
	 * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
	 */
	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub

	}

}